home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 030 (1988-11)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 030 (1988-11)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / dis / main.c < prev    next >
C/C++ Source or Header  |  1988-11-12  |  7KB  |  422 lines

  1. #include "dis.h"
  2.  
  3. #define NTSTART 20
  4.  
  5. char *cur_file = NULL;            /* the file thats open */
  6. int  pre_index = 0;
  7. int  tstart[NTSTART];            /* .trace directive keep locations */
  8. int  tstarti = 0;
  9.  
  10. VALUE token;
  11.  
  12. #ifdef AMIGA
  13. unsigned char *d,*f; /* Manx has a bug preventing us from declaring arrays >64K */
  14. extern unsigned char *calloc();
  15. #else
  16. unsigned char d[0x10000];         /* The data */
  17. unsigned char f[0x10000];        /* Flags for memory usage */ 
  18. #endif
  19.  
  20. #define RUNLOC  0x2e0
  21. #define INITLOC 0x2e2
  22.  
  23. main(argc, argv)
  24. int argc;
  25. char *argv[];
  26. {
  27.     int i;
  28.  
  29. #ifdef AMIGA
  30. d = calloc(0x10000,1);
  31. f = calloc(0x10000,1);
  32. #endif
  33.  
  34.     initopts(argc, argv);
  35.     if (npredef > 0) {
  36.         cur_file = predef[0];
  37.         pre_index++;
  38.         yyin = fopen(cur_file, "r");
  39.         if (!yyin)
  40.             crash ("Cant open predefine file");
  41.         get_predef();
  42.     }
  43.     switch (bopt) {
  44.         case 0:
  45.             loadboot();
  46.             break;
  47.         case 1:
  48.             loadfile();
  49.             break;
  50.         case 2:
  51.             c64loadfile();
  52.             break;
  53.         }
  54.     for (i = 0; i<tstarti; i++)
  55.         start_trace(tstart[i], "*PTRACE*");
  56.  
  57.     dumpitout();
  58.  
  59. #ifdef AMIGA
  60. free(d);
  61. free(f);
  62. #endif
  63.  
  64.     exit(0);
  65. }
  66.  
  67. crash(p)
  68. char *p;
  69. {
  70.     fprintf(stderr, "%s: %s\n", progname, p);
  71.     if (cur_file != NULL)
  72.         fprintf(stderr, "Line %d of %s\n", lineno+1, cur_file);
  73. #ifdef AMIGA
  74. free(d);
  75. free(f);
  76. #endif
  77.     exit(1);
  78. }
  79.  
  80. get_predef()
  81. {
  82.     int loc;
  83.     char *name;
  84.  
  85.     for(;;) 
  86.         switch (yylex()) {
  87.         case '\n':
  88.             break;
  89.         case 0:
  90.             return;
  91.         case TSTART:
  92.             if (yylex() != NUMBER) 
  93.                 crash(".trace needs a number operand");
  94.             loc = token.ival;
  95.             if (loc > 0x10000 || loc < 0)
  96.                 crash("Number out of range");
  97.             if (tstarti == NTSTART) 
  98.                 crash("Too many .trace directives");
  99.             tstart[tstarti++] = loc;
  100.             while (yylex() != '\n')
  101.                 ;
  102.             break;
  103.         case TSTOP:
  104.             if (yylex() != NUMBER) 
  105.                 crash(".stop needs a number operand");
  106.             loc = token.ival;
  107.             if (loc > 0x10000 || loc < 0)
  108.                 crash("Number out of range");
  109.             f[loc] |= TDONE;
  110.             while (yylex() != '\n')
  111.                 ;
  112.             break;
  113.         case NUMBER:
  114.             switch (yylex()) {
  115.             case LI:
  116.             case COMMENT:
  117.                 while (yylex() != '\n')
  118.                     ;
  119.                 break;
  120.             case '\n':
  121.                 break;
  122.             case NAME:
  123.                 name = token.sval;
  124.                 if (yylex() != EQ) 
  125.                     crash("Only EQ and LI supported in defines file");
  126.                 if (yylex() != NUMBER)
  127.                     crash("EQ operand must be a number");
  128.                 loc = token.ival;
  129.                 if (loc > 0x10000 || loc < 0)
  130.                     crash("Number out of range");
  131.                 f[loc] |= NAMED;
  132.                 save_name(loc, name); 
  133.                 while (yylex() != '\n') 
  134.                     ;
  135.                 break;
  136.             default:
  137.                 crash("Invalid line in predef file");
  138.             }
  139.             break;
  140.         default:
  141.             crash("Invalid line in predef file");
  142.         }
  143. }
  144.  
  145. loadboot()
  146. {
  147.     struct boot_hdr {
  148.         unsigned char flags;
  149.         unsigned char nsec;
  150.         unsigned char base_low;
  151.         unsigned char base_hi;
  152.         unsigned char init_low;
  153.         unsigned char init_hi;
  154.     } bh;
  155.  
  156.     FILE *fp;
  157.     int base_addr;
  158.     register int i;
  159.     int len;
  160.  
  161.     fp = fopen(file, "r");
  162.     cur_file = NULL;
  163.     if (!fp) { 
  164.         fprintf(stderr, "Cant open %s\n", file);
  165.  
  166. #ifdef AMIGA
  167. free(d);
  168. free(f);
  169. #endif
  170.  
  171.         exit(1);
  172.     }
  173.  
  174.     if(fread((char *)&bh, sizeof(bh), 1, fp) != 1) 
  175.         crash("Input too short");
  176.     
  177.     base_addr = bh.base_low + (bh.base_hi << 8);
  178.     len = bh.nsec * 128;
  179.     rewind(fp);
  180.     if (fread((char *)&d[base_addr], 1, len, fp) != len) 
  181.         crash("input too short");
  182.  
  183.     for(i = base_addr; len > 0; len--) 
  184.         f[i++] |= LOADED;
  185.  
  186.     start_trace(base_addr+6, "**BOOT**");
  187. }
  188.  
  189.  
  190. loadfile()
  191. {
  192.     FILE *fp;
  193.     int base_addr;
  194.     int last_addr;
  195.     register int i;
  196.     int had_header;
  197.     int tmp;
  198.  
  199.     had_header = 0;
  200.     fp = fopen(file, "r");
  201.     cur_file = NULL;
  202.     if (!fp) { 
  203.         fprintf(stderr, "Cant open %s\n", file);
  204.  
  205. #ifdef AMIGA
  206. free(d);
  207. free(f);
  208. #endif
  209.  
  210.         exit(1);
  211.     }
  212.     for(;;) {
  213.  
  214.         i = getc(fp);
  215.  
  216.         if (i == EOF) {
  217.             if (f[RUNLOC] & LOADED & f[RUNLOC+1]) {
  218.                 i = getword(RUNLOC);
  219.                 start_trace(i, "**RUN**");
  220.             }
  221.             return;
  222.         }
  223.  
  224.         i = i | (getc(fp) << 8);
  225.         if (i == 0xffff)  {
  226.             had_header = 1;
  227.             base_addr = getc(fp);
  228.             base_addr = base_addr | (getc(fp) << 8);
  229.             if (base_addr < 0 || base_addr > 0xffff) 
  230.                 crash("Invalid base addr in input file");
  231.         } else {
  232.             if (!had_header)
  233.                 crash("Invalid header in input file");
  234.             base_addr = i;
  235.         }
  236.  
  237.         last_addr = getc(fp);
  238.         last_addr = last_addr | (getc(fp) << 8);
  239.         if (last_addr < base_addr || last_addr > 0xffff) 
  240.             crash("Invalid length in input file");
  241.  
  242.         printf("Load:  %4x -> %4x\n", base_addr, last_addr);
  243.         for(i = base_addr; i <= last_addr; i++) {
  244.             tmp = getc(fp);
  245.             if (tmp == EOF) 
  246.                 crash("File too small");
  247.             d[i] = tmp;
  248.             f[i] |= LOADED;
  249.         }
  250.  
  251.         if (f[INITLOC] & LOADED & f[INITLOC+1])  {
  252.             i = getword(INITLOC);
  253.             start_trace(i, "**INIT**");
  254.         }
  255.  
  256.         f[INITLOC] &= ~LOADED;
  257.         f[INITLOC+1] &= ~LOADED;
  258.     }
  259.  
  260. }
  261.  
  262.  
  263. c64loadfile()
  264. {
  265.     FILE *fp;
  266.     unsigned int base_addr,i;
  267.     int c;
  268.  
  269.     fp = fopen(file, "r");
  270.     cur_file = NULL;
  271.     if (!fp) { 
  272.         fprintf(stderr, "Cant open %s\n", file);
  273.  
  274. #ifdef AMIGA
  275.         free(d);
  276.         free(f);
  277. #endif
  278.  
  279.         exit(1);
  280.     }
  281.  
  282.     base_addr = getc(fp);
  283.     i = ( base_addr += ( (unsigned int)getc(fp) << 8 ) );
  284.  
  285.     while( (c = getc(fp)) != EOF) {
  286.         d[i] = c;
  287.         f[i++] |= LOADED;
  288.         }
  289.  
  290.     start_trace(base_addr, "**C64BIN**");
  291. }
  292.  
  293.  
  294. start_trace(loc, name)
  295. unsigned int loc;
  296. char *name;
  297. {
  298.     printf("Trace: %4x %s\n", loc, name);
  299.     f[loc] |= (NAMED | SREF);
  300.     if (!get_name(loc))
  301.         save_name(loc, name);
  302.     save_ref(0, loc);
  303.     trace(loc);
  304. }
  305.     
  306. trace(addr)
  307. register unsigned int addr;
  308. {
  309.     int opcode;
  310.     register struct info *ip; 
  311.     int operand;
  312.     int istart;
  313.  
  314.     if (f[addr] & TDONE)
  315.         return;
  316.     else 
  317.         f[addr] |= TDONE;
  318.  
  319.     istart = addr;
  320.     opcode = getbyte(addr);
  321.     ip = &optbl[opcode];
  322.  
  323.     if (ip->flag & ILL)
  324.         return;
  325.  
  326.     f[addr] |= ISOP;
  327.  
  328.     addr++;
  329.  
  330.     /* Get the operand */
  331.  
  332.     switch(ip->nb) {
  333.         case 1:
  334.             break;
  335.         case 2:
  336.             operand = getbyte(addr);
  337.             f[addr++] |= TDONE;
  338.             break;
  339.         case 3:
  340.             operand = getword(addr);
  341.             f[addr++] |= TDONE;
  342.             f[addr++] |= TDONE;
  343.             break;
  344.     }
  345.  
  346.     /* Mark data references */
  347.  
  348.     switch (ip->flag & ADRMASK) {
  349.         case IMM:
  350.         case ACC:
  351.         case IMP:
  352.         case REL:
  353.         case IND:
  354.             break;
  355.         case ABS:
  356.             if (ip->flag & (JUMP | FORK))
  357.                 break;
  358.             /* Fall into */
  359.         case ABX:
  360.         case ABY:
  361.         case INX:
  362.         case INY:
  363.         case ZPG:
  364.         case ZPX:
  365.         case ZPY:
  366.             f[operand] |= DREF;
  367.             save_ref(istart, operand);
  368.             break;
  369.         default:
  370.             crash("Optable error");
  371.             break;
  372.     }
  373.  
  374.     /* Trace the next instruction */
  375.  
  376.     switch (ip->flag & CTLMASK) {
  377.         case NORM:
  378.             trace(addr);
  379.             break;
  380.         case JUMP:
  381.             f[operand] |= JREF;
  382.             save_ref(istart, operand);
  383.             trace(operand);
  384.             break;
  385.         case FORK:
  386.             if (ip->flag & REL) {
  387.                 if (operand > 127) 
  388.                     operand = (~0xff | operand);
  389.                 operand = operand + addr;
  390.                 f[operand] |= JREF;
  391.             } else {
  392.                 f[operand] |= SREF;
  393.             }
  394.             save_ref(istart, operand);
  395.             trace(operand);
  396.             trace(addr);
  397.             break;
  398.         case STOP:
  399.             break;
  400.         default:
  401.             crash("Optable error");
  402.             break;
  403.     }
  404. }
  405.  
  406. int
  407. yywrap()
  408. {
  409.     (void)fclose(yyin);
  410.     if (npredef == pre_index) {
  411.         return(1);
  412.     } else  {
  413.         lineno = 0;
  414.         cur_file = predef[pre_index];
  415.         pre_index++;
  416.         yyin = fopen(cur_file, "r");
  417.         if (!yyin) 
  418.             crash("Can't open predefines file");
  419.         return (0);
  420.     }
  421. }
  422.